/*
 * Copyright (C) 2008-2011 CBDP Consortium
 * 
 * All rights reserved.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution.
 * 
 * This software consists of contributions made by many individuals, 
 * listed below:
 *
 * Author: 	Xabier Laiseca <xabier.laiseca@deusto.es>
 * 			David Ausín <david.ausin@deusto.es>
 */
package cbdp.server.contextreasoner.impl.creator;

import org.osgi.framework.BundleContext;

import cbdp.server.contextreasoner.configuration.OntologyConfigurationLoader;
import cbdp.server.contextreasoner.configuration.exceptions.OntologyConfigurationLoaderException;
import cbdp.server.contextreasoner.configuration.model.Configuration;
import cbdp.server.contextreasoner.impl.contextmanager.online.JenaContextManager;
import cbdp.server.contextreasoner.impl.contextmanager.online.wrappers.ContextManagerLockerWrapper;
import cbdp.server.contextreasoner.impl.contextmanager.online.wrappers.ContextManagerRuleLaunchingWrapper;
import cbdp.server.contextreasoner.impl.reasoner.GenericReasoner;
import cbdp.server.contextreasoner.impl.reasoner.jena.JenaReasoner;
import cbdp.server.contextreasoner.internal.InternalContextManager;
import cbdp.server.contextreasoner.internal.OntologyContainer;
import cbdp.server.contextreasoner.internal.containers.MemoryOntologyContainer;
import cbdp.server.contextreasoner.internal.containers.SDBOntologyContainer;
import cbdp.server.contextreasoner.internal.containers.TDBOntologyContainer;

public class ServiceCreator
{
	private final static String DEFAULT_CONFIGURATION_FILE_LOCATION = "/resources/configuration/configuration.xml";
	
	private JenaContextManager jcm;
	
	private OntologyContainer ontologyContainer;
	private InternalContextManager contextManager;
	private GenericReasoner genericReasoner;
	
	private BundleContext bc;
	
	private Configuration configuration;
	
	
	public void createServices(final BundleContext bc)
	{
		createServices(bc, null);
	}
	
	public void createServices(final BundleContext bc, final String configurationFile)
	{
		this.bc = bc;
		
		loadConfiguration(configurationFile);
		createContextManager();
		createReasoner();
	}

	public OntologyContainer getOntologyContainer()
	{
		return ontologyContainer;
	}

	public InternalContextManager getContextManager()
	{
		return contextManager;
	}

	public GenericReasoner getGenericReasoner()
	{
		return genericReasoner;
	}
	
	public Configuration getConfiguration()
	{
		return configuration;
	}
	
	
	/* ********************* Private methods ********************* */
	
	private void loadConfiguration(final String configurationFile)
	{
		try
		{
			if (configurationFile != null)
			{
				configuration = OntologyConfigurationLoader.load(configurationFile);
			}
			else
			{
				configuration = OntologyConfigurationLoader.load(DEFAULT_CONFIGURATION_FILE_LOCATION);
			}
		}
		catch (OntologyConfigurationLoaderException e)
		{
			configuration = new Configuration();
			e.printStackTrace();
		}
	}
	
	private void createContextManager()
	{
		ontologyContainer = createOntologyContainer();
		
		jcm = new JenaContextManager(bc);
		jcm.setConfiguration(configuration);
		jcm.setOntologyContainer(ontologyContainer);
		jcm.load();
		
		final ContextManagerRuleLaunchingWrapper cmrlw = new ContextManagerRuleLaunchingWrapper();
		cmrlw.setContextManager(jcm);
		
		final ContextManagerLockerWrapper ljcm = new ContextManagerLockerWrapper();
		ljcm.setOntologyContainer(ontologyContainer);
		ljcm.setContextManager(cmrlw);
		contextManager = ljcm;
	}
	
	private OntologyContainer createOntologyContainer()
	{
		OntologyContainer ontologyContainer;
		
		switch (configuration.getStorageType())
		{
			case SDB:
				ontologyContainer = new SDBOntologyContainer();
				break;
				
			case TDB:
				ontologyContainer = new TDBOntologyContainer();
				break;
				
			case MEMORY:
			default:
				ontologyContainer = new MemoryOntologyContainer();
				break;
		}
		
		ontologyContainer.setConfiguration(configuration);
		ontologyContainer.load();
		
		return ontologyContainer;
	}
	
	private void createReasoner()
	{
		final String reasonerClassName = configuration.getReasonerClassName();
		
		try
		{
			final Class<?> reasonerClass = Class.forName(reasonerClassName);
			final Class<? extends GenericReasoner> genericReasonerClass = reasonerClass.asSubclass(GenericReasoner.class);
			genericReasoner = genericReasonerClass.newInstance();
		}
		catch (Exception e)
		{
			genericReasoner = new JenaReasoner();
		}
		
		genericReasoner.setOntologyContainer(ontologyContainer);
		
		jcm.setReasoner(genericReasoner);
		
		genericReasoner.load();
	}
}
